// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2005-01-19

#include "stdafx.h"
#include "base_text.h"

namespace JoyServer
{

namespace TextLib
{

static const BYTE s_FirstByteMark[7] =
{
    0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
};

bool UTF8_Decode(wchar_t* dstBuf, int& dstLen, const void* srcBuf, int srcLen)
{
    dstBuf;dstLen;srcBuf;srcLen;
    return true;
}

bool UTF8_Encode(void* dstBuf, int& dstLen, const wchar_t* srcBuf, int srcLen)
{
    if (!srcLen)
    {
        dstLen = 0;
        return true;
    }
    if(!dstLen)
    {
        return false;
    }

    const wchar_t* srcPtr = srcBuf;
    const wchar_t* srcEnd = srcPtr + srcLen;
    BYTE* outPtr = (BYTE*)dstBuf;
    BYTE* outEnd = outPtr + dstLen;

    while (srcPtr < srcEnd)
    {
        UINT curVal = *srcPtr;

        //
        //  If its a leading surrogate, then lets see if we have the trailing
        //  available. If not, then give up now and leave it for next time.
        //
        unsigned int srcUsed = 1;
        if ((curVal >= 0xD800) && (curVal <= 0xDBFF))
        {
            if (srcPtr + 1 >= srcEnd)
                break;

            // Create the composite surrogate pair
            curVal = ((curVal - 0xD800) << 10)
                    + ((*(srcPtr + 1) - 0xDC00) + 0x10000);

            // And indicate that we ate another one
            srcUsed++;
        }

        // Figure out how many bytes we need
        unsigned int encodedBytes;
        if (curVal < 0x80)
            encodedBytes = 1;
        else if (curVal < 0x800)
            encodedBytes = 2;
        else if (curVal < 0x10000)
            encodedBytes = 3;
        else if (curVal < 0x110000)
            encodedBytes = 4;
        else
        {
            // If the options say to throw, then throw

            // Else, use the replacement character
            *outPtr++ = ' '; //chSpace;
            srcPtr += srcUsed;
            continue;
        }

        //
        //  If we cannot fully get this char into the output buffer,
        //  then leave it for the next time.
        //
        if (outPtr + encodedBytes > outEnd)
            break;

        // We can do it, so update the source index
        srcPtr += srcUsed;

        //
        //  And spit out the bytes. We spit them out in reverse order
        //  here, so bump up the output pointer and work down as we go.
        //
        outPtr += encodedBytes;
        switch(encodedBytes)
        {
            case 6 : *--outPtr = BYTE((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 5 : *--outPtr = BYTE((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 4 : *--outPtr = BYTE((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 3 : *--outPtr = BYTE((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 2 : *--outPtr = BYTE((curVal | 0x80UL) & 0xBFUL);
                     curVal >>= 6;
            case 1 : *--outPtr = BYTE
                     (
                        curVal | s_FirstByteMark[encodedBytes]
                     );
        }

        // Add the encoded bytes back in again to indicate we've eaten them
        outPtr += encodedBytes;
    }

    // Fill in the chars we ate
    // charsEaten = (srcPtr - srcData);

    // And return the bytes we filled in
    dstLen = (int)(size_t)(outPtr - (BYTE*)dstBuf);
    return true;
}

};



} // namespace JoyServer